package com.msimple.order.port.adapter.controller;

import com.msimple.order.application.OrderApplicationService;
import com.msimple.order.application.representation.OrderRepresentationService;
import com.msimple.sdk.command.order.ChangeAddressDetailCommand;
import com.msimple.sdk.command.order.ChangeProductCountCommand;
import com.msimple.sdk.command.order.CreateOrderCommand;
import com.msimple.sdk.command.order.PayOrderCommand;
import com.msimple.sdk.representation.order.OrderRepresentation;
import com.msimple.sdk.representation.order.OrderSummaryRepresentation;
import com.msimple.shared.utils.PagedResource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.Map;

import static com.google.common.collect.ImmutableMap.of;
import static org.springframework.http.HttpStatus.CREATED;

/**
 *  order rest api controller
 * @Title:      OrderController
 * @Package:    OrderController
 * @Author:     M.simple
 * @Remark:     The modified content
 * @CreateDate: 2019-10-12 10:17
 * @Version:    v2.0
 */
@RestController
@RequestMapping(value = "/orders")
public class OrderController {
    
    private final OrderApplicationService applicationService;
    
    private final OrderRepresentationService representationService;

    public OrderController(OrderApplicationService applicationService,
                           OrderRepresentationService representationService) {
        this.applicationService = applicationService;
        this.representationService = representationService;
    }

    /**
     * create order
     * @method      createOrder
     * @param       command:
     * @return      Map<String, String>
     * @author      M.simple
     * @date        2019-10-12 10:18
     * @version     v2.0
     */
    @PostMapping
    @ResponseStatus(CREATED)
    public Map<String, String> createOrder(@RequestBody @Valid CreateOrderCommand command) {
        return of("id", applicationService.createOrder(command));
    }

    /**
     * change order product count
     * @method      changeProductCount
     * @param       id:comand
     * @return      
     * @author      M.simple
     * @date        2019-10-1 15:36
     * @version     v2.0
     */
    @PostMapping("/{id}/products")
    public void changeProductCount(@PathVariable(name = "id") String id, @RequestBody @Valid ChangeProductCountCommand command) {
        applicationService.changeOrderProductCount(id, command);
    }

    /**
     * order payment
     * @method      pay
     * @param       id:comand
     * @return
     * @author      M.simple
     * @date        2019-10-1 15:36
     * @version     v2.0
     */
    @PostMapping("/{id}/payment")
    public void pay(@PathVariable(name = "id") String id, @RequestBody @Valid PayOrderCommand command) {
        applicationService.orderPay(id, command);
    }

    /**
     * change order adress detail
     * @method      changeAddressDetail
     * @param       id:comand
     * @return
     * @author      M.simple
     * @date        2019-10-1 15:36
     * @version     v2.0
     */
    @PostMapping("/{id}/address/detail")
    public void changeAddressDetail(@PathVariable(name = "id") String id, @RequestBody @Valid ChangeAddressDetailCommand command) {
        applicationService.changeAddressDetail(id, command.getDetail());
    }

    /**
     * quere order info
     * @method      changeAddressDetail
     * @param       id:comand
     * @return
     * @author      M.simple
     * @date        2019-10-1 15:36
     * @version     v2.0
     */
    @GetMapping("/{id}")
    public OrderRepresentation byId(@PathVariable(name = "id") String id) {
        return representationService.byId(id);
    }

    /**
     * page list order info
     * @method      changeAddressDetail
     * @param       pageIndex:pageSize
     * @return
     * @author      M.simple
     * @date        2019-10-1 15:36
     * @version     v2.0
     */
    @GetMapping
    public PagedResource<OrderSummaryRepresentation> pagedProducts(@RequestParam(required = false, defaultValue = "1") int pageIndex,
                                                                   @RequestParam(required = false, defaultValue = "10") int pageSize) {
        return representationService.listOrders(pageIndex, pageSize);
    }


}
